package cn.edu.hitwh.kanlema.service.impl;

import cn.edu.hitwh.kanlema.constant.MqConstants;
import cn.edu.hitwh.kanlema.constant.RedisConstants;
import cn.edu.hitwh.kanlema.entity.CinemaType;
import cn.edu.hitwh.kanlema.mapper.CinemaTypeMapper;
import cn.edu.hitwh.kanlema.message.RebuildCacheMessage;
import cn.edu.hitwh.kanlema.service.ICinemaTypeService;
import cn.edu.hitwh.kanlema.util.RedisCache;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author vvcoder
 * @since 2025-8-18
 */
@Service
public class CinemaTypeServiceImpl extends ServiceImpl<CinemaTypeMapper, CinemaType> implements ICinemaTypeService {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        List<CinemaType> list = lambdaQuery().orderByAsc(CinemaType::getSort).list();
        redisCache.setWithLogicalExpire(
                RedisConstants.CACHE_CINEMA_TYPE_KEY,
                list,
                RedisConstants.CACHE_CINEMA_TYPE_TTL,
                TimeUnit.MINUTES
        );
    }

    @Override
    public List<CinemaType> getTypeList() {
        String json = redisCache.getWithLogicalExpire(
                RedisConstants.CACHE_CINEMA_TYPE_KEY,
                () -> {
                    String lockKey = RedisConstants.HOT_KEY_LOCK_PREFIX + RedisConstants.CACHE_CINEMA_TYPE_KEY;
                    if (redisCache.tryLock(lockKey, RedisConstants.HOT_KEY_LOCK_TTL, TimeUnit.SECONDS)) {
                        RebuildCacheMessage message = new RebuildCacheMessage();
                        message.setCacheKey(RedisConstants.CACHE_CINEMA_TYPE_KEY);
                        message.setLockKey(lockKey);
                        rabbitTemplate.convertAndSend(
                                MqConstants.HOT_KEY_REBUILD_EXCHANGE,
                                MqConstants.CINEMA_TYPE_REBUILD_KEY,
                                message
                        );
                    }
                }
        );
        return JSONUtil.toList(json, CinemaType.class);
    }
}
